;; protocol/osc-decode.scm - (c) rohan drape, 2002-2005

;; Evaluates to the <string> encoded at the OSC <u8vector> `b'.  This
;; deletes the zero padding at the end of the string.

(define (osc-decode/scan-string b)
  (u8vector->string 
   (u8vector-copy b 0 (u8vector-index b 0))))

;; Evaluates to the <u8vector> encoded at the OSC <u8vector> `b'.

(define (osc-decode/scan-bytes b)
  (u8vector-copy b 4 (+ 4 (decode-int32 (u8vector-copy b 0 4)))))

;; Evaluates to a pair, the car cell holds the object, described by
;; the OSC type character `type', encoded at the OSC <u8vector> `b'.

(define (osc-decode/scan-value type b)
  (cond ((eq? type #\i)
	 (decode-int32 b))
	((eq? type #\h)
	 (decode-int64 b))
	((eq? type #\t)
	 (decode-uint64 b))
	((eq? type #\f)
	 (decode-float32 b))
	((eq? type #\d)
	 (decode-float64 b))
	((eq? type #\s)
	 (osc-decode/scan-string b))
	((eq? type #\b)
	 (osc-decode/scan-bytes b))
	(else
	 (error "osc-decode-value: Bad type character" type))))

;; Since a pure decode without shared u8vectors is very inefficient,
;; defer to osc-read-* forms.

(define (osc-decode-message b)
  (osc-read/scan-message (open-input-u8vector b)))

(define (osc-decode-bundle b)
  (osc-read/scan-bundle (open-input-u8vector b)))

;; Evaluate to the scheme representation of the OSC packet encoded at
;; the OSC <u8vector> `b' starting at the integer offset `start'.  An
;; OSC packet is either an OSC message or an OSC bundle.

(define (osc-decode-packet b)
  (if (= (u8vector-ref b 0) (char->integer #\#))
      (osc-decode-bundle b)
      (osc-decode-message b)))
